package com.springboot.common.handler;

import com.springboot.common.annotation.SQLDate;
import org.springframework.core.MethodParameter;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;

/**
 * @SQLDate   时间字段默认赋值处理类  基于MVC
 */
@Deprecated
public class SQLDateHandlerBACK implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        System.out.println("parameter.hasParameterAnnotation(SQLDate.class) = " + parameter.hasParameterAnnotation(SQLDate.class));
        return parameter.hasParameterAnnotation(SQLDate.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {

        HttpServletRequest nativeRequest = webRequest.getNativeRequest(HttpServletRequest.class);
        Enumeration<String> parameterNames = nativeRequest.getParameterNames();

        Object o = parameter.getNestedParameterType().newInstance();

        while (parameterNames.hasMoreElements()){
            final String name = parameterNames.nextElement();
            Field e = ReflectionUtils.findField(o.getClass(), name);

            setValue(o, e, nativeRequest.getParameter(name));
        }

        Arrays.asList(o.getClass().getDeclaredFields())
                .stream()
                .forEach(e -> {
                    if(e.getDeclaredAnnotation(SQLDate.class) == null) return;
                    final Date date = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());
                    setValue(o, e, date);

                });
        return o;
    }

    private void setValue(Object o, Field e, Object v) {
        if(e.isAccessible()){
            ReflectionUtils.setField(e, o, v);
        }else{
            e.setAccessible(true);
            ReflectionUtils.setField(e, o, v);
            e.setAccessible(false);
        }
    }
}
